<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 * 
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 * 
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://code.google.com/p/feather-cm
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

class GenericAuthorModel extends ActiveRecord
{
	protected $belongsTo        = array('Member');
	protected $moduleClass;
	protected $filerRoot;
	public    $recursiveProcess = Q_PROCESS_LIST;
	public    $recursiveFields  = 'member_id';
	
	function beforeFind()
	{
		$this->_join = 'INNER';
	}
	
	# READ
	
	function & getList($limit=null, $page=null)
	{
		$this->unbind(array('belongsTo' => $this->moduleClass));
		$this->process = Q_PROCESS_LIST;
		return $this->findAll('DISTINCT Member.id', $limit, $page, 0);
		/*
		$this->Member->unbind(array('belongsTo' => $this->moduleClass));
		$this->Member->bind(array('hasOne' => $this->name));
		$this->Member->process = Q_PROCESS_LIST;
		$this->Member->_join = 'INNER';
		return $this->Member->findAll('DISTINCT Member.id', $limit, $page, 0);
		*/
	}
	
	function & getListFor($id, $limit=null, $page=null)
	{
		$this->unbind(array('belongsTo' => 'Member'));
		$this->condition("{$this->name}.member_id", $id);
		$this->order('Webcomic.updated DESC');
		return $this->findAll("{$this->moduleClass}.id, {$this->moduleClass}.domain, {$this->moduleClass}.title", $limit, $page, 0);
	}
	
	function countFor($id, $private=true)
	{
		$this->unbind(array('belongsTo' => 'Member'));
		$this->condition("{$this->name}.member_id", $id);
		return $this->findCount(0);
	}
	
	function & getListRandom($limit=null, $page=null)
	{
		$this->order('RAND()');
		$this->unbind(array('belongsTo' => $this->moduleClass));
		return $this->getList($limit, $page);
	}
	
	function & getRandom()
	{
		$this->order('RAND()');
		$this->unbind(array('belongsTo' => '*'));
		$user = $this->find("DISTINCT {$this->name}.member_id", 1);
		
		if (!empty($user))
			$user[$this->moduleClass] = $this->getListFor($user[$this->name]['member_id']);
		
		return $user;
	}
	
	# validate
	
	function validates($data=null)
	{
		if (empty($this->data[$this->name]['members']))
		{
			$this->validationErrors[$this->name]['members'] = _("There must be at least one author.");
			return false;
		}
		return true;
	}
	
	# create, update & delete
	
	protected function __save($type=null)
	{
		# referer
		$module     = $this->{$this->moduleClass};
		$module_key = $module->foreignKey;
		$module_id  = $module->id;
		
		# authors
		$authors = array_list($this->data[$this->name]['members'], ',;\s');
		
		if (!empty($authors))
		{
			# each author _must_ have an account
			$this->Member->process  = Q_PROCESS_LITE;
			$this->Member->conditions(array('id' => &$authors));
			$authors = $this->Member->listField('id', -1);
			$this->data[$this->name]['members'] = $authors;
		}
		
		# already defined authors
		$this->conditions(array($module_key => $module_id));
		$_authors = $this->listField('member_id', -1);
		
		$new_authors = array_diff($authors, $_authors);
		$del_authors = array_diff($_authors, $authors);
		
		# removed authors
		if (!empty($del_authors))
		{
			foreach ($del_authors as $member_id)
				$this->destroyAcl("User.$member_id");
			if (!$this->__delete_all(array($module_key => $module_id, 'member_id' => &$del_authors)))
				return false;
		}
		
		# new authors
		if (!empty($new_authors))
		{
			$values = array();
			foreach($new_authors as $member_id)
			{
				$this->createAcl("User.$member_id");
				array_push($values, array($module_id, $member_id));
			}
			
			if (!$this->saveMany(array($module_key, 'member_id'), &$values))
				return false;
		}
		
		return true;
	}
	
	# ACL
	
	function createAcl($aro=null, $action='grant')
	{
		$Acl = new AclComponent();
		$aco = "{$this->moduleClass}.{$this->{$this->moduleClass}->id}";
		($action != 'destroy') ? $Acl->{$action}($aro, $aco) : $Acl->destroy($aco, $aro);
	}
	
	function destroyAcl($aro=null)
	{
		$this->createAcl($aro, 'destroy');
	}
	
	protected function __delete_all(array $conditions)
	{
		if (empty($conditions))
			return false;
		$conditions = $this->db->conditions($conditions);
		
		# deletes
		$rs = $this->db->execute("DELETE FROM {$this->table} $conditions ;");
		
		# finishes
		$this->__reset();
		return $rs;
	}
}
?>
